package com.sca.order.sharding;

import lombok.extern.slf4j.Slf4j;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;

import java.util.Collection;

/**
 * @author liuxianfei
 * @since 2020/11/13 09:45
 */
@Slf4j
public class DatabaseShardingAlgorithm implements PreciseShardingAlgorithm<Long> {

    @Override
    public String doSharding(Collection<String> dbNames, PreciseShardingValue<Long> preciseShardingValue) {
        int virtualNode = 360;
        String virtualNodeRang = "0-179,180-359";
        int mod = preciseShardingValue.getValue().hashCode() % virtualNode;
        if (mod < 0) {
            mod = Math.abs(mod);
        }

        Integer shardingValue = getPhysicNodeByVisualNode(mod, virtualNodeRang);
        for (String each : dbNames) {
            if (each.endsWith(String.valueOf(shardingValue))) {
                log.debug("logic DB : {}", each);
                return each;
            }
        }
        throw new IllegalArgumentException("分库参数配置异常");
    }

    private Integer getPhysicNodeByVisualNode(int mod, String virtualNodeCountRang) {
        String[] rangArr = virtualNodeCountRang.split(",");
        Integer physicCount = null;
        for (int i = 0; i < rangArr.length; i++) {
            String[] tmpArr = rangArr[i].split("-");
            if ((mod >= Integer.parseInt(tmpArr[0])) && (mod <= Integer.parseInt(tmpArr[1]))) {
                physicCount = i;
                break;
            }
        }
        return physicCount;
    }

}
